{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "# Interactive monitoring of a parallel MPI simulation from a notebook\n",
    "\n",
    "first, start a cluster with mpi.\n",
    "\n",
    "Or load an existing cluster with e.g.\n",
    "\n",
    "```python\n",
    "cluster = Cluster.from_file(profile=\"mpi\")\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from IPython.display import display\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using existing profile dir: '/Users/minrk/.ipython/profile_default'\n",
      "Starting 4 engines with <class 'ipyparallel.cluster.launcher.MPIEngineSetLauncher'>\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8b14b3b6f0cb4a67be4645c8274c4074",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/4 [00:00<?, ?engine/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import ipyparallel as ipp\n",
    "n = 4\n",
    "\n",
    "rc = ipp.Cluster(engines=\"mpi\", n=n).start_and_connect_sync()\n",
    "\n",
    "view = rc[:]\n",
    "rc.ids"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "Now, we load the MPI libraries into the engine namespaces, and do a simple printing of their MPI rank information to verify that all nodes are operational and they match our cluster's real capacity.  \n",
    "\n",
    "Here, we are making use of IPython's special `%%px` cell magic, which marks the entire cell for parallel execution.  This means that the code below will not run in this notebook's kernel, but instead will be sent to *all* engines for execution there.  In this way, IPython makes it very natural to control your entire cluster from within the notebook environment:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[stdout:0] MPI rank: 0/4\n",
      "[stdout:1] MPI rank: 1/4\n",
      "[stdout:2] MPI rank: 2/4\n",
      "[stdout:3] MPI rank: 3/4\n"
     ]
    }
   ],
   "source": [
    "%%px --block\n",
    "# MPI initialization, library imports and sanity checks on all engines\n",
    "from mpi4py import MPI\n",
    "import numpy as np\n",
    "import time\n",
    "\n",
    "mpi = MPI.COMM_WORLD\n",
    "bcast = mpi.bcast\n",
    "barrier = mpi.barrier\n",
    "rank = mpi.rank\n",
    "print(\"MPI rank: %i/%i\" % (mpi.rank,mpi.size))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "We write a utility that reorders a list according to the mpi ranks of the engines, since all gather operations will return data in engine id order, not in MPI rank order.  We'll need this later on when we want to reassemble in IPython data structures coming from all the engines: IPython will collect the data ordered by engine ID, but our code creates data structures based on MPI rank, so we need to map from one indexing scheme to the other.  This simple function does the job:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [],
   "source": [
    "ranks = view['rank']\n",
    "rank_indices = np.argsort(ranks)\n",
    "\n",
    "def mpi_order(seq):\n",
    "    \"\"\"Return elements of a sequence ordered by MPI rank.\n",
    "\n",
    "    The input sequence is assumed to be ordered by engine ID.\"\"\"\n",
    "    return [seq[x] for x in rank_indices]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "## MPI simulation example"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "This is our 'simulation', a toy example that computes $\\sin(f(x^2+y^2))$ for a slowly increasing frequency $f$ over a gradually refined mesh.  In a real-world example, there typically is a 'simulate' method that, afer setting up initial parameters, runs the entire computation.  But having this simple example will be sufficient to see something that changes visually as the computation evolves and that is quick enough for us to test.\n",
    "\n",
    "And while simple, this example has a realistic decomposition of the spatial domain in one array per MPI node that requires care in reordering the data for visualization, as would be needed in a real-world application (unless your code accumulates data in the rank 0 node that you can grab directly)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [],
   "source": [
    "%%px --block\n",
    "\n",
    "stop = False\n",
    "nsteps = 100\n",
    "delay = 0.1\n",
    "\n",
    "xmin, xmax = 0, np.pi\n",
    "ymin, ymax = 0, 2 * np.pi\n",
    "dy = (ymax - ymin) / mpi.size\n",
    "\n",
    "\n",
    "def simulation():\n",
    "    \"\"\"Toy simulation code, computes sin(f*(x**2+y**2)) for a slowly increasing f\n",
    "    over an increasingly fine mesh.\n",
    "\n",
    "    The purpose of this code is simply to illustrate the basic features of a typical\n",
    "    MPI code: spatial domain decomposition, a solution which is evolving in some\n",
    "    sense, and local per-node computation.  In this case the nodes don't really\n",
    "    communicate at all.\n",
    "    \"\"\"\n",
    "    # By making these few variables global, we allow the IPython client to access them\n",
    "    # remotely for interactive introspection\n",
    "    global j, Z, nx, nyt\n",
    "    freqs = np.linspace(0.6, 1, nsteps)\n",
    "    for j in range(nsteps):\n",
    "        nx, ny = 2 + j // 4, 2 + j // 2 // mpi.size\n",
    "        nyt = mpi.size * ny\n",
    "        Xax = np.linspace(xmin, xmax, nx)\n",
    "        Yax = np.linspace(\n",
    "            ymin + rank * dy, ymin + (rank + 1) * dy, ny, endpoint=rank == mpi.size\n",
    "        )\n",
    "        X, Y = np.meshgrid(Xax, Yax)\n",
    "        f = freqs[j]\n",
    "        Z = np.cos(f * (X ** 2 + Y ** 2))\n",
    "        # We add a small delay to simulate that a real-world computation\n",
    "        # would take much longer, and we ensure all nodes are synchronized\n",
    "        time.sleep(delay)\n",
    "        # The stop flag can be set remotely via IPython, allowing the simulation to be\n",
    "        # cleanly stopped from the outside\n",
    "        if stop:\n",
    "            break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "## IPython tools to interactively monitor and plot the MPI results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "We now define a local (to this notebook) plotting function that fetches data from the engines' global namespace.  Once it has retrieved the current state of the relevant variables, it produces and returns a figure:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import clear_output\n",
    "\n",
    "def plot_current_results(in_place=True):\n",
    "    \"\"\"Makes a blocking call to retrieve remote data and displays the solution mesh\n",
    "    as a contour plot.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    in_place : bool\n",
    "        By default it calls clear_output so that new plots replace old ones.  Set\n",
    "        to False to allow keeping of all previous outputs.\n",
    "    \"\"\"\n",
    "    \n",
    "    # We make a blocking call to load the remote data from the simulation into simple named \n",
    "    # variables we can read from the engine namespaces\n",
    "    #view.apply_sync(load_simulation_globals)\n",
    "    # And now we can use the view to read these variables from all the engines.  Then we\n",
    "    # concatenate all of them into single arrays for local plotting\n",
    "    try:\n",
    "        Z = np.concatenate(mpi_order(view['Z']))\n",
    "    except ValueError:\n",
    "        print(\"dimension mismatch in Z, not plotting\")\n",
    "        ax = plt.gca()\n",
    "        return ax.figure\n",
    "        \n",
    "    nx, nyt, j, nsteps = view.pull(['nx', 'nyt', 'j', 'nsteps'], targets=0, block=True)\n",
    "    fig, ax = plt.subplots()\n",
    "    ax.contourf(Z)\n",
    "    ax.set_title('Mesh: %i x %i, step %i/%i' % (nx, nyt, j+1, nsteps))\n",
    "    plt.axis('off')\n",
    "    # We clear the notebook output before plotting this if in-place plot updating is requested\n",
    "    if in_place:\n",
    "        clear_output(wait=True)\n",
    "    display(fig)\n",
    "    return fig"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "It will also be useful to be able to check whether the simulation is still alive or not.  Below we will wrap the main simulation function into a thread to allow IPython to pull data from the engines, and we will call this object `simulation_thread`.  So to check whether the code is still running, all we have to do is call the `is_alive` method on all of our engines and see whether any of them returns True:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [],
   "source": [
    "def simulation_alive():\n",
    "    \"\"\"Return True if the simulation thread is still running on any engine.\n",
    "    \"\"\"\n",
    "    return any(view.apply_sync(lambda : simulation_thread.is_alive()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "Finally, this is a convenience wrapper around the plotting code so that we can interrupt monitoring at any point, and that will provide basic timing information:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [],
   "source": [
    "def monitor_simulation(refresh=5.0, plots_in_place=True):\n",
    "    \"\"\"Monitor the simulation progress and call plotting routine.\n",
    "\n",
    "    Supress KeyboardInterrupt exception if interrupted, ensure that the last \n",
    "    figure is always displayed and provide basic timing and simulation status.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    refresh : float\n",
    "      Refresh interval between calls to retrieve and plot data.  The default\n",
    "      is 5s, adjust depending on the desired refresh rate, but be aware that \n",
    "      very short intervals will start having a significant impact.\n",
    "\n",
    "    plots_in_place : bool\n",
    "       If true, every new figure replaces the last one, producing a (slow)\n",
    "       animation effect in the notebook.  If false, all frames are plotted\n",
    "       in sequence and appended in the output area.\n",
    "    \"\"\"\n",
    "    import datetime as dt, time\n",
    "    \n",
    "    if not simulation_alive():\n",
    "        plot_current_results(in_place=plots_in_place)\n",
    "        plt.close('all')\n",
    "        print('Simulation has already finished, no monitoring to do.')\n",
    "        return\n",
    "    \n",
    "    t0 = dt.datetime.now()\n",
    "    fig = None\n",
    "    try:\n",
    "        while simulation_alive():\n",
    "            fig = plot_current_results(in_place=plots_in_place)\n",
    "            plt.close('all') # prevent re-plot of old figures\n",
    "            time.sleep(refresh) # so we don't hammer the server too fast\n",
    "    except (KeyboardInterrupt, TimeoutError):\n",
    "        msg = 'Monitoring interrupted, simulation is ongoing!'\n",
    "    else:\n",
    "        msg = 'Simulation completed!'\n",
    "    tmon = dt.datetime.now() - t0\n",
    "    if plots_in_place and fig is not None:\n",
    "        clear_output(wait=True)\n",
    "        plt.close('all')\n",
    "        display(fig)\n",
    "    print(msg)\n",
    "    print('Monitored for: %s.' % tmon)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "## Making a simulation object that can be monitored interactively"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [],
   "source": [
    "%%px --block\n",
    "from threading import Thread\n",
    "\n",
    "stop = False\n",
    "nsteps = 100\n",
    "delay = 0.5\n",
    "# Create a thread wrapper for the simulation. The target must be an argument-less\n",
    "# function so we wrap the call to 'simulation' in a simple lambda:\n",
    "simulation_thread = Thread(target=lambda: simulation())\n",
    "# Now we actually start the simulation\n",
    "simulation_thread.start()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x444.984 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 365,
       "width": 572
      }
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Monitoring interrupted, simulation is ongoing!\n",
      "Monitored for: 0:00:19.277042.\n"
     ]
    }
   ],
   "source": [
    "monitor_simulation(refresh=1);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "source": [
    "If you execute the following cell before the MPI code is finished running, it will stop the simulation at that point, which you can verify by calling the monitoring again:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "slideshow": {
     "slide_start": false
    }
   },
   "outputs": [],
   "source": [
    "view['stop'] = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[stdout:0] \n",
      "{\n",
      "  \"shell_port\": 57579,\n",
      "  \"iopub_port\": 57580,\n",
      "  \"stdin_port\": 57581,\n",
      "  \"control_port\": 57583,\n",
      "  \"hb_port\": 57582,\n",
      "  \"ip\": \"127.0.0.1\",\n",
      "  \"key\": \"944dac79-816e4a12e48b45baf11ab5e8\",\n",
      "  \"transport\": \"tcp\",\n",
      "  \"signature_scheme\": \"hmac-sha256\",\n",
      "  \"kernel_name\": \"\"\n",
      "}\n",
      "\n",
      "Paste the above JSON into a file, and connect with:\n",
      "    $> jupyter <app> --existing <file>\n",
      "or, if you are local, you can connect with just:\n",
      "    $> jupyter <app> --existing /Users/minrk/.ipython/profile_default/security/kernel-46128.json\n",
      "or even just:\n",
      "    $> jupyter <app> --existing\n",
      "if this is the most recent Jupyter kernel you have started.\n"
     ]
    }
   ],
   "source": [
    "%%px --target 0 --block\n",
    "from ipyparallel import bind_kernel; bind_kernel()\n",
    "%connect_info"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%px --target 0 --block\n",
    "%qtconsole"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {
     "02f2d94254d542bdbd3cff7f9bc035e7": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "FloatProgressModel",
      "state": {
       "bar_style": "success",
       "layout": "IPY_MODEL_4cdefd8ae5764be8a8bf1f3c374492f0",
       "max": 4,
       "style": "IPY_MODEL_d101b978f358462fbcc0ad51c4be1ee1",
       "value": 4
      }
     },
     "0ab41c84c30445dfa2c77e0e2014dd46": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "1.2.0",
      "model_name": "LayoutModel",
      "state": {}
     },
     "11097de7cc114cc88d99cd17a693d510": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "1.2.0",
      "model_name": "LayoutModel",
      "state": {}
     },
     "20d1375897eb4fdcb87fda73573ad678": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "HBoxModel",
      "state": {
       "children": [
        "IPY_MODEL_7a50e71a222340a4ba51e70ef3abce47",
        "IPY_MODEL_02f2d94254d542bdbd3cff7f9bc035e7",
        "IPY_MODEL_876517d46fa6488f8fb61db3ed689b96"
       ],
       "layout": "IPY_MODEL_0ab41c84c30445dfa2c77e0e2014dd46"
      }
     },
     "212854fc12af402eb3a57438a851dfac": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "DescriptionStyleModel",
      "state": {
       "description_width": ""
      }
     },
     "2231573544774560984193c60e6370cb": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "1.2.0",
      "model_name": "LayoutModel",
      "state": {}
     },
     "4205fec62aea485c8ffaf31ca98859aa": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "1.2.0",
      "model_name": "LayoutModel",
      "state": {}
     },
     "4cdefd8ae5764be8a8bf1f3c374492f0": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "1.2.0",
      "model_name": "LayoutModel",
      "state": {}
     },
     "5143e78c3dcc439a95b7ec24ea37c2be": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "DescriptionStyleModel",
      "state": {
       "description_width": ""
      }
     },
     "6817e30d6c824bd194e102e20a9e7cda": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "DescriptionStyleModel",
      "state": {
       "description_width": ""
      }
     },
     "6be3837161754e08a715ac0c78fa1080": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "1.2.0",
      "model_name": "LayoutModel",
      "state": {}
     },
     "7a50e71a222340a4ba51e70ef3abce47": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "HTMLModel",
      "state": {
       "layout": "IPY_MODEL_2231573544774560984193c60e6370cb",
       "style": "IPY_MODEL_6817e30d6c824bd194e102e20a9e7cda",
       "value": "100%"
      }
     },
     "7afda4d37ef841c684bb624ff6b19267": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "DescriptionStyleModel",
      "state": {
       "description_width": ""
      }
     },
     "811e5930f3bc42899a5e700d9b275bdb": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "1.2.0",
      "model_name": "LayoutModel",
      "state": {}
     },
     "876517d46fa6488f8fb61db3ed689b96": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "HTMLModel",
      "state": {
       "layout": "IPY_MODEL_11097de7cc114cc88d99cd17a693d510",
       "style": "IPY_MODEL_7afda4d37ef841c684bb624ff6b19267",
       "value": " 4/4 [00:05&lt;00:00,  5.54s/engine]"
      }
     },
     "88e7ff230d284b368ace25166967a93d": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "HTMLModel",
      "state": {
       "layout": "IPY_MODEL_6be3837161754e08a715ac0c78fa1080",
       "style": "IPY_MODEL_5143e78c3dcc439a95b7ec24ea37c2be",
       "value": "100%"
      }
     },
     "8b14b3b6f0cb4a67be4645c8274c4074": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "HBoxModel",
      "state": {
       "children": [
        "IPY_MODEL_88e7ff230d284b368ace25166967a93d",
        "IPY_MODEL_eee11ad7360e4cc2b6b2f196ff4a1d45",
        "IPY_MODEL_9d0e878210c24c93bc764ec9ec53b84e"
       ],
       "layout": "IPY_MODEL_a15b2b7fec55486689859c321b2ca7e3"
      }
     },
     "9d0e878210c24c93bc764ec9ec53b84e": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "HTMLModel",
      "state": {
       "layout": "IPY_MODEL_811e5930f3bc42899a5e700d9b275bdb",
       "style": "IPY_MODEL_212854fc12af402eb3a57438a851dfac",
       "value": " 4/4 [00:06&lt;00:00,  6.12s/engine]"
      }
     },
     "a15b2b7fec55486689859c321b2ca7e3": {
      "model_module": "@jupyter-widgets/base",
      "model_module_version": "1.2.0",
      "model_name": "LayoutModel",
      "state": {}
     },
     "afa1055878c444c49c4db6767994e04b": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "ProgressStyleModel",
      "state": {
       "description_width": ""
      }
     },
     "d101b978f358462fbcc0ad51c4be1ee1": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "ProgressStyleModel",
      "state": {
       "description_width": ""
      }
     },
     "eee11ad7360e4cc2b6b2f196ff4a1d45": {
      "model_module": "@jupyter-widgets/controls",
      "model_module_version": "1.5.0",
      "model_name": "FloatProgressModel",
      "state": {
       "bar_style": "success",
       "layout": "IPY_MODEL_4205fec62aea485c8ffaf31ca98859aa",
       "max": 4,
       "style": "IPY_MODEL_afa1055878c444c49c4db6767994e04b",
       "value": 4
      }
     }
    },
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
